package com.sap.sap_mangers.controller;

import com.sap.sap_mangers.dto.Join.*;
import com.sap.sap_mangers.pojo.SapJoinApplication;
import com.sap.sap_mangers.pojo.SapJoinManager;
import com.sap.sap_mangers.service.UserService;
import com.sap.sap_mangers.until.ConstantUntil;
import com.sap.sap_mangers.until.JwtUtil;
import com.sap.sap_mangers.until.LimitCallFrequencyUntil;
import com.sap.sap_mangers.until.SimpleJson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 新生入会(升级正式会员) controller
 *
 * @author ZhouKai
 * 2022/8/23 9:27
 */
@RestController
@RequestMapping("/Join")
public class JoinController {
    @Autowired
    private UserService userService;
    @Autowired
    private LimitCallFrequencyUntil limitCallFrequencyUntil;

    /**
     * 填充入会管理表
     * 会长权限，事务支持，操作同步
     * 清空表(同时删除所有付款码的cos储存)，插入所有管理层
     *
     * @return json
     */
    @PreAuthorize("hasAuthority('会长')")
    @PostMapping("/fillJoinManagerTable")
    public SimpleJson fillJoinManagerTable() {
        String userForToken = JwtUtil.getUserForToken();
        String presidentUserName = userService.getPresidentUsername();
        if (!presidentUserName.equals(userForToken)) {
            //只允许会长使用
            return new SimpleJson(1, "权限不足");
        }
        //事务处理
        try {
            userService.fillJoinManagerTable();
        } catch (Exception e) {
            e.printStackTrace();
            return new SimpleJson(2, "未知异常，事务回滚");
        }
        return SimpleJson.SUCCESS;
    }

    /**
     * 设置或撤销正式管理员职责
     * 只允许会长操作
     * 即可用于设置(备用->正式)，也可用于撤销(正式->备用)
     *
     * @param change 被操作的管理员的学号
     * @return Json
     */
    @PreAuthorize("hasAuthority('会长')")
    @PostMapping("/changeJoinManagerResponsible")
    public SimpleJson changeJoinManagerResponsible(@RequestBody ChangeManagerResponsible change) {
        return userService.changeJoinManagerResponsible(change.getUsername());
    }

    /**
     * (负责人)上传收款码
     *
     * @param collectionCode 收款码
     * @param type           收款码类型 (0:微信；1:支付宝)
     * @return Json
     */
    @PreAuthorize("hasAuthority('管理员')")
    @PostMapping("/setCollectionCode")
    public SimpleJson setCollectionCode(@RequestParam("collectionCode") MultipartFile collectionCode,
                                        @RequestParam("type") Integer type) {
        //事务处理
        SimpleJson json;
        try {
            json = userService.setCollectionCode(collectionCode, type);
        } catch (Exception e) {
            e.printStackTrace();
            return new SimpleJson(6, "事务异常");
        }
        return json;
    }

    /**
     * (负责人)清空收款码
     *
     * @param delete 收款码种类 (0:微信；1:支付宝)
     * @return Json
     */
    @PreAuthorize("hasAuthority('管理员')")
    @PostMapping("/deleteCollectionCode")
    public SimpleJson deleteCollectionCode(@RequestBody DeleteCode delete) {
        SimpleJson json;
        try {
            json = userService.deleteCollectionCode(delete.getType());
        } catch (Exception e) {
            e.printStackTrace();
            return new SimpleJson(3, "事务异常");
        }
        return json;
    }

    /**
     * 点击入会(升级)按钮
     * <p>
     * 已是会员直接返回
     * 没有填写单号提交申请会 返回 负责人姓名/qq/收款码 (记录过期或管理员已失效会重新匹配负责人)
     * 已提交申请(提交转账单号)但还没处理 返回 负责人姓名/qq，邀请码，填写的转账单号(用于自己核对) (已填写单号的记录不会过期)
     *
     * @return Json
     */
    @PreAuthorize("hasAuthority('游客')")
    @GetMapping("/clickJoinButton")
    public SimpleJson clickJoinButton() {
        if (!userService.getSapIfOpenJoinFunction()) {
            return new SimpleJson(8, "入会升级功能暂未开启!请联系管理员");
        }
        SimpleJson json;
        try {
            json = userService.clickJoinButton();
        } catch (Exception e) {
            e.printStackTrace();
            return new SimpleJson(5, "事务异常");
        }
        return json;
    }

    /**
     * 提交入会申请
     *
     * @param submit 转账单号
     * @return Json
     */
    @PreAuthorize("hasAuthority('游客')")
    @PostMapping("/submitApplication")
    public SimpleJson submitApplication(@RequestBody SubmitApplication submit) {
        if (!userService.getSapIfOpenJoinFunction()) {
            return new SimpleJson(8, "入会升级功能暂未开启!请联系管理员");
        }
        try {
            return userService.submitApplication(submit.getPaymentTransferNumber());
        } catch (Exception e) {
            return new SimpleJson(3, "服务器异常");
        }
    }

    /**
     * 审核
     * 增加判断：每分钟只能调用10次
     *
     * @param examine 收款单号和邀请码
     * @return Json
     */
    @PreAuthorize("hasAuthority('管理员')")
    @PostMapping("/toExamine")
    public SimpleJson toExamine(@RequestBody Examine examine) {
        //每分钟调用次数限制 10次
        if (!limitCallFrequencyUntil.limitCallFrequencyPerMinute(ConstantUntil.SAP_AUDIT_JOIN_NUM_PER_MINUTE, 10)) {
            return new SimpleJson(6,"接口调用已达上限，请下一分钟再调用");
        }
        try {
            return userService.toExamine(examine.getPaymentTransferNumber(), examine.getInvitationCode());
        } catch (Exception e) {
            e.printStackTrace();
            return new SimpleJson(6, "服务器异常");
        }
    }

    /**
     * 获取当前是否开启入会升级接口(入会申请相关接口)
     *
     * @return 当前是否开启入会升级接口
     */
    @PreAuthorize("hasAuthority('游客')")
    @GetMapping("/getIfOpenJoinFunction")
    public SimpleJson getSapIfOpenJoinFunction() {
        boolean sapIfOpenJoinFunction;
        try {
            sapIfOpenJoinFunction = userService.getSapIfOpenJoinFunction();
        } catch (Exception e) {
            return new SimpleJson(2, "redis异常");
        }
        return sapIfOpenJoinFunction ? new SimpleJson(0, "当前开启了入会升级功能") : new SimpleJson(1, "当前关闭了入会升级功能");
    }

    /**
     * 开启/关闭 入会升级接口(入会申请相关接口)
     */
    @PreAuthorize("hasAuthority('会长')")
    @PostMapping("/updateIfOpenJoinFunction")
    public SimpleJson updateSapIfOpenJoinFunction() {
        return userService.updateSapIfOpenJoinFunction();
    }

    /**
     * 查询所有管理员的信息视图
     * (按role表的编号排序)
     *
     * @return 管理员信息视图
     */
    @PreAuthorize("hasAuthority('正式成员')")
    @GetMapping("/getJoinManagerVos")
    public SimpleJson getJoinManagerVos() {
        return new SimpleJson(0, "成功", userService.getJoinManagerVos());
    }

    /**
     * 通过邀请码获取对应申请记录信息
     *
     * @param invitationCode 邀请码
     * @return 申请记录信息
     */
    @PreAuthorize("hasAuthority('管理员')")
    @GetMapping("/getJoinApplicationByCode")
    public SimpleJson getJoinApplicationByCode(@RequestParam("invitationCode") String invitationCode) {
        //检测是否为管理员调用
        String userForToken = JwtUtil.getUserForToken();
        SapJoinManager joinManager = userService.getSapJoinManager(userForToken);
        if (joinManager == null) {
            return new SimpleJson(2, "权限不足");
        }
        //查询返回
        SapJoinApplication joinApplication = userService.getJoinApplicationByCode(invitationCode);
        return joinApplication == null ? new SimpleJson(1, "没有查询到对应信息") : new SimpleJson(0, "查询成功", joinApplication);
    }

    /**
     * 查询异常的申请记录 (填写了单号但未成功处理) -> 填写了转账单号的记录不会过期，系统审核通过才算处理成功
     *
     * @return 填写了单号但未成功处理的申请记录 (不排除单号是乱填的的可能)
     */
    @PreAuthorize("hasAuthority('管理员')")
    @GetMapping("/getAbnormalJoinApplication")
    public SimpleJson getAbnormalJoinApplication() {
        //检测是否为管理员
        if (userService.getSapJoinManager(JwtUtil.getUserForToken()) == null) {
            return new SimpleJson(1, "权限不足");
        }
        return new SimpleJson(0, "获取成功", userService.getAbnormalJoinApplication());
    }

    /**
     * 清空单号
     * <p>
     * 允许将填写了单号但没成功处理的申请记录中的单号清空 (用于清空乱填的转账单号)
     *
     * @param clear 申请人学号
     * @return Json
     */
    @PreAuthorize("hasAuthority('会长')")
    @PostMapping("/clearPaymentTransferNumber")
    public SimpleJson clearJoinApplicationPaymentTransferNumber(@RequestBody ClearTransferNumber clear) {
        //检测操作人是不是会长
        if (userService.getUserByUserName(JwtUtil.getUserForToken()).getRole() != 1) {
            return new SimpleJson(1, "权限不足");
        }
        return userService.clearJoinApplicationPaymentTransferNumber(clear.getUsername());
    }

    /**
     * (管理员)查询自己需要负责审核的入会申请
     *
     * @return 管理员负责的、提交了单号的入会记录
     */
    @PreAuthorize("hasAuthority('管理员')")
    @GetMapping("/getSubmittedJoinsByManager")
    public SimpleJson getSubmittedJoinApplicationByManager() {
        Map<String, List<SapJoinApplication>> submittedJoins = userService.getSubmittedJoinApplicationByManager();
        return submittedJoins == null ? new SimpleJson(0, "暂无数据") : new SimpleJson(0, "获取成功", submittedJoins);
    }

    /**
     * 直接升级会员
     * @return 处理结果
     */
    @PreAuthorize("hasAuthority('管理员')")
    @GetMapping("/directUpgrade")
    SimpleJson directUpgrade(@RequestBody DirectUpgrade upgrade) {
        String username = upgrade.getUsername();
        String accounting = upgrade.getAccounting();
        try {
            return userService.directUpgrade(username, accounting);
        } catch (Exception e) {
            e.printStackTrace();
            return new SimpleJson(6, "服务器异常");
        }
    }
}
